/**
 * @Description:
 * @Author 卞鹏飞 <228443632@qq.com>
 * @create 06/02/25 PM12:49
 */

import { prompt } from 'inquirer'
import path from 'node:path'
import fs from 'node:fs'
import makeDir from 'make-dir'
import memFs from 'mem-fs'
import FileEditor from 'mem-fs-editor'

interface Env {
  rootPath: string
  error: (message?: any, ...optionalParams: any[]) => void
}

class AppEntryBase {
  log = console.log
  async: () => () => void
  prompt: (questions: any, answers?: any) => Promise<any>
  makeDir: typeof makeDir
  env: Env
  fs: InstanceType<typeof FileEditor>

  constructor() {
    this.async = () => () => {}
    this.prompt = prompt
    this.makeDir = makeDir

    this.env = {
      rootPath: process.cwd(),
      error: console.error
    }

    const store = memFs.create()
    this.fs = FileEditor.create(store)
  }

  /* 初始化函数 */
  initializing() {}

  /* 接收用户输入阶段 */
  prompting() {}

  /* 编辑和配置项目的配置文件 */
  configuring() {}

  /* 生成项目目录结构阶段 */
  writing() {}

  /* 安装依赖 */
  install() {}

  /* 生成器结束阶段, clean工作 */
  end() {}

  /**
   * Join a path to the destination root.
   * @param  {...string} paths
   * @return {string} joined path
   */
  destinationPath(...paths: string[]): string {
    let filepath = path.join(...paths)
    if (!path.isAbsolute(filepath)) {
      filepath = path.join(this.destinationRoot(), filepath)
    }
    return filepath
  }

  /**
   * Change the generator destination root directory.
   * This path is used to find storage, when using a file system helper method (like
   * `this.write` and `this.copy`)
   * @param  {string} rootPath new destination root path
   * @return {string} destination root path
   */
  destinationRoot(rootPath?: string): string {
    if (typeof rootPath === 'string') {
      this._destinationRoot = path.resolve(rootPath)

      if (!fs.existsSync(rootPath)) {
        makeDir.sync(rootPath)
      }

      process.chdir(rootPath)

      // Reset the storage
      // this.config = this._getStorage();
    }

    return this._destinationRoot || this.env.rootPath
  }

  private _destinationRoot: string | undefined
}

export default AppEntryBase
